home *** CD-ROM | disk | FTP | other *** search
- ///--------------------------------------------------------------------------------------
- // Split-Screen Demo.c
- //
- // By Vern Jensen. Created 3/8/97
- ///--------------------------------------------------------------------------------------
-
-
- #include <SWFPSReport.h>
- #include <SWIncludes.h>
- #include <SWGameUtils.h>
- #include "SWApplication.h"
- #include "Multi-Screen Scrolling.h"
-
- #include "Split-Screen Demo.h"
- #include "Sprite Stuff.h"
-
-
- #define kInterlacedMode false // Turns Interlaced mode on/off
- #define kSyncToVBL false // Sync SpriteWorld to VBL?
- #define kMaxFPS 30 // Set to 0 for unrestricted speed
- #define kLavaFrameRate 7 // Change lava tile every X frames
-
-
-
- /***********/
- /* Globals */
- /***********/
-
- WindowPtr gWindowP;
- SpriteWorldPtr gMasterSpriteWorldP, gCloneSpriteWorldP;
- SpriteLayerPtr gTankSpriteLayerP, gBulletSpriteLayerP, gPowerUpSpriteLayerP;
- TileMapStructPtr gTileMapStructP;
- TileMapPtr gTileMap;
- Rect gMasterRect, gCloneRect; // The world rects for each SpriteWorld
- Rect gMoveBoundsRect;
- DrawProcPtr gSpriteMaskDrawProc;
- RgnHandle gTempRgn; // Used by TankHitDrawProc
-
- KeyStruct gTank1Keys, gTank2Keys; // Structures containing keys for each tank
-
-
-
-
- ///--------------------------------------------------------------------------------------
- // Main
- ///--------------------------------------------------------------------------------------
-
- void main( void )
- {
- Initialize(kNumberOfMoreMastersCalls);
-
- if (SWHasSystem7())
- {
- gTempRgn = NewRgn(); // Create temp region
- AllowKeyUpEvents(); // Part of SWGameUtils.c
- SetCursor(*GetCursor(watchCursor));
-
- CreateSpriteWorlds();
- LoadSprites();
- CreateTankSprites();
-
- SetCursor(&qd.arrow);
- HideCursor();
-
- SetUpAnimation();
- RunAnimation();
- ShutDown();
-
- DisposeRgn(gTempRgn); // Dispose temp region
- RestoreEventMask(); // Call this after AllowKeyUpEvents
- }
- else
- {
- CantRunOnThisMachine();
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateSpriteWorlds
- ///--------------------------------------------------------------------------------------
-
- void CreateSpriteWorlds( void )
- {
- Rect offscreenRect, windRect;
- OSErr err;
-
- gWindowP = GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
-
- if (gWindowP != NULL)
- {
- // Calculate the size of the window
- windRect.top = 0;
- windRect.left = 0;
- windRect.right = qd.screenBits.bounds.right - 20;
- windRect.bottom = qd.screenBits.bounds.bottom / 2;
-
- // Calculate the rects for each SpriteWorld
- gMasterRect = gCloneRect = windRect;
- gMasterRect.right = gMasterRect.right/2 - 15;
- gCloneRect.left = gMasterRect.right + 30;
-
- // Center the window in the screen
- SizeWindow(gWindowP, windRect.right, windRect.bottom, false);
- CenterRect(&windRect, &qd.screenBits.bounds);
- MoveWindow(gWindowP, windRect.left, windRect.top, false);
-
- ShowWindow(gWindowP);
- SetPort(gWindowP);
- }
- else
- CantFindResource();
-
-
- err = SWEnterSpriteWorld();
- FatalError(err);
-
-
- // Set size of offscreen area
- offscreenRect = gMasterRect;
- OffsetRect(&offscreenRect, -offscreenRect.left, -offscreenRect.top);
-
-
- // Make offscreen area evenly divisible by tile width & height
- if ( (offscreenRect.right/kTileWidth)*kTileWidth != offscreenRect.right)
- offscreenRect.right = (offscreenRect.right/kTileWidth)*kTileWidth + kTileWidth;
-
- if ( (offscreenRect.bottom/kTileHeight)*kTileHeight != offscreenRect.bottom)
- offscreenRect.bottom = (offscreenRect.bottom/kTileHeight)*kTileHeight + kTileHeight;
-
-
- // Create the Master SpriteWorld
- err = SWCreateSpriteWorldFromWindow(&gMasterSpriteWorldP, (CWindowPtr)gWindowP,
- &gMasterRect, &offscreenRect, 0);
- FatalError(err);
-
- // Create the Clone SpriteWorld
- err = SWCreateSpriteWorldFromWindow(&gCloneSpriteWorldP, (CWindowPtr)gWindowP,
- &gCloneRect, &offscreenRect, 0);
- FatalError(err);
-
-
- // Init Tiling for the Master SpriteWorld
- err = SWInitTiling(gMasterSpriteWorldP, kTileHeight, kTileWidth, kMaxNumTiles);
- FatalError(err);
-
- // Init Tiling for the Clone SpriteWorld
- err = SWInitTilingForDuplicateSpriteWorld(gCloneSpriteWorldP, kTileHeight, kTileWidth);
- FatalError(err);
-
-
- err = SWLoadTileMap(&gTileMapStructP, 128);
- FatalError(err);
-
- SWInstallTileMap(gMasterSpriteWorldP, gTileMapStructP, 0);
- gTileMap = gTileMapStructP->tileMap;
-
-
- // Load wall tiles
- err = SWLoadTilesFromPictResource(
- gMasterSpriteWorldP,
- kFirstWallTile, // startTileID
- kLastWallTile, // endTileID
- 200, // pictResID
- 0, // maskResID
- kNoMask, // maskType
- 0, // horizBorderWidth
- 0); // vertBorderHeight
- FatalError(err);
-
- // Load floor tiles
- err = SWLoadTilesFromPictResource(
- gMasterSpriteWorldP,
- kFirstFloorTile, // startTileID
- kMudTile, // endTileID
- 201, // pictResID
- 0, // maskResID
- kNoMask, // maskType
- 0, // horizBorderWidth
- 0); // vertBorderHeight
- FatalError(err);
-
- // Load lava tiles
- err = SWLoadTilesFromPictResource(
- gMasterSpriteWorldP,
- kFirstLavaTile, // startTileID
- kLastLavaTile, // endTileID
- 202, // pictResID
- 0, // maskResID
- kNoMask, // maskType
- 0, // horizBorderWidth
- 0); // vertBorderHeight
- FatalError(err);
-
- // Create the sprite layers
- err = SWCreateSpriteLayer(&gPowerUpSpriteLayerP);
- FatalError(err);
- err = SWCreateSpriteLayer(&gBulletSpriteLayerP);
- FatalError(err);
- err = SWCreateSpriteLayer(&gTankSpriteLayerP);
- FatalError(err);
-
- // Add them to the Master SpriteWorld
- SWAddSpriteLayer(gMasterSpriteWorldP, gPowerUpSpriteLayerP); // Bottom layer
- SWAddSpriteLayer(gMasterSpriteWorldP, gBulletSpriteLayerP); // Middle layer
- SWAddSpriteLayer(gMasterSpriteWorldP, gTankSpriteLayerP); // Top layer
-
- // Lock both SpriteWorlds
- SWLockSpriteWorld(gMasterSpriteWorldP);
- SWLockSpriteWorld(gCloneSpriteWorldP);
-
-
- // Set the gSpriteMaskDrawProc before loading sprites
- if (gMasterSpriteWorldP->pixelDepth == 8)
- {
- gSpriteMaskDrawProc = CompiledSprite8BitDrawProc;
- }
- else if ( !(SW_PPC && gMasterSpriteWorldP->pixelDepth < 8) )
- {
- if (kInterlacedMode)
- gSpriteMaskDrawProc = BPAllBitInterlacedMaskDrawProc;
- else
- gSpriteMaskDrawProc = BlitPixieAllBitMaskDrawProc;
- }
- else
- {
- gSpriteMaskDrawProc = SWStdSpriteDrawProc;
- }
-
- SetRect(&gMoveBoundsRect, 0,0,
- gMasterSpriteWorldP->tileLayerArray[0]->numCols * kTileWidth,
- gMasterSpriteWorldP->tileLayerArray[0]->numRows * kTileHeight);
- SWSetScrollingWorldMoveBounds(gMasterSpriteWorldP, &gMoveBoundsRect);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateTankSprites
- ///--------------------------------------------------------------------------------------
-
- void CreateTankSprites( void )
- {
- SpritePtr mySpriteP;
- TankStructPtr tankStructP;
-
- // Create the sprite on the left
- mySpriteP = NewTankSprite(kPlayer1);
- tankStructP = (TankStructPtr)mySpriteP;
-
- SWSetSpriteLocation(mySpriteP, gMoveBoundsRect.left + 120, gMoveBoundsRect.top + 100);
- SWSetScrollingWorldMoveProc(gMasterSpriteWorldP, ScrollingWorldMoveProc, mySpriteP);
-
- // Create the sprite on the right
- mySpriteP = NewTankSprite(kPlayer2);
- tankStructP = (TankStructPtr)mySpriteP;
-
- SWSetSpriteLocation(mySpriteP, gMoveBoundsRect.right-140, gMoveBoundsRect.bottom-140);
- SWSetScrollingWorldMoveProc(gCloneSpriteWorldP, ScrollingWorldMoveProc, mySpriteP);
-
- // Create the power-up sprites
- mySpriteP = NewPowerUpSprite(kMachineGun);
- SWSetSpriteLocation(mySpriteP, gMoveBoundsRect.right - 140, gMoveBoundsRect.top + 120);
-
- mySpriteP = NewPowerUpSprite(kMachineGun);
- SWSetSpriteLocation(mySpriteP, gMoveBoundsRect.left + 130, gMoveBoundsRect.bottom - 160);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SetUpAnimation
- ///--------------------------------------------------------------------------------------
-
- void SetUpAnimation( void )
- {
- SWSetSpriteWorldMaxFPS(gMasterSpriteWorldP, kMaxFPS);
- SWSyncSpriteWorldToVBL(gMasterSpriteWorldP, kSyncToVBL);
- SWSetCleanUpSpriteWorld(gMasterSpriteWorldP);
-
- SWSetTileChangeProc(gMasterSpriteWorldP, TileChangeProc);
-
- // Move visScrollRect to starting sprite position
- SWMoveVisScrollRect(gMasterSpriteWorldP,
- gMasterSpriteWorldP->followSpriteP->destFrameRect.left - gMasterSpriteWorldP->backRect.right/2,
- gMasterSpriteWorldP->followSpriteP->destFrameRect.top - gMasterSpriteWorldP->backRect.bottom/2);
-
-
- // Set the various DrawProcs
- if (gMasterSpriteWorldP->pixelDepth == 8) // If in 256 colors
- {
- if (kInterlacedMode)
- {
- SWSetSpriteWorldScreenDrawProc(gMasterSpriteWorldP, BP8BitInterlacedRectDrawProc);
- SWSetSpriteWorldOffscreenDrawProc(gMasterSpriteWorldP, BP8BitInterlacedRectDrawProc);
- SWSetDoubleRectDrawProc(gMasterSpriteWorldP, BP8BitInterlacedDoubleRectDrawProc);
- }
- else
- {
- SWSetSpriteWorldOffscreenDrawProc(gMasterSpriteWorldP, BlitPixie8BitRectDrawProc);
- SWSetSpriteWorldScreenDrawProc(gMasterSpriteWorldP, BlitPixie8BitRectDrawProc);
- SWSetDoubleRectDrawProc(gMasterSpriteWorldP, BlitPixie8BitDoubleRectDrawProc);
- }
- }
- else if ( !(SW_PPC && gMasterSpriteWorldP->pixelDepth < 8) ) // Not 256 colors
- {
- if (kInterlacedMode && gMasterSpriteWorldP->pixelDepth != 1)
- {
- // Use interlaced drawProcs unless in B&W, where interlacing is ugly
- SWSetSpriteWorldScreenDrawProc(gMasterSpriteWorldP, BPAllBitInterlacedRectDrawProc);
- SWSetSpriteWorldOffscreenDrawProc(gMasterSpriteWorldP, BPAllBitInterlacedRectDrawProc);
- if (gMasterSpriteWorldP->pixelDepth == 16)
- SWSetDoubleRectDrawProc(gMasterSpriteWorldP, BP16BitInterlacedDoubleRectDrawProc);
- }
- else
- {
- SWSetSpriteWorldOffscreenDrawProc(gMasterSpriteWorldP, BlitPixieAllBitRectDrawProc);
- SWSetSpriteWorldScreenDrawProc(gMasterSpriteWorldP, BlitPixieAllBitRectDrawProc);
- if (gMasterSpriteWorldP->pixelDepth == 16)
- SWSetDoubleRectDrawProc(gMasterSpriteWorldP, BlitPixie16BitDoubleRectDrawProc);
- }
- }
-
- // Make sure CopyBits, if used, doesn't try to colorize things
- SWSetPortToWindow(gMasterSpriteWorldP);
- ForeColor(blackColor);
- BackColor(whiteColor);
-
-
- // Copy information from the Master SpriteWorld to the Clone SpriteWorld
- SWSetUpDuplicateSpriteWorld(gMasterSpriteWorldP, gCloneSpriteWorldP);
-
-
- SWDrawTilesInBackground(gMasterSpriteWorldP);
- SWDrawTilesInBackground(gCloneSpriteWorldP);
- SWUpdateScrollingSpriteWorld(gMasterSpriteWorldP, true);
- SWUpdateScrollingSpriteWorld(gCloneSpriteWorldP, true);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // RunAnimation
- ///--------------------------------------------------------------------------------------
-
- void RunAnimation( void )
- {
- unsigned long frames;
-
- frames = 0;
- StartTimer();
-
- FatalError( SWStickyError() ); // Make sure no errors got past us during setup
-
- while (!Button())
- {
- UpdateKeys();
- SWProcessSpriteWorld(gMasterSpriteWorldP);
-
- if (gMasterSpriteWorldP->frameHasOccurred)
- {
- SWProcessMultiScreenSpriteWorld(gMasterSpriteWorldP);
- SWProcessMultiScreenSpriteWorld(gCloneSpriteWorldP);
-
- SWCollideSpriteLayer(gMasterSpriteWorldP, gBulletSpriteLayerP, gTankSpriteLayerP);
- SWCollideSpriteLayer(gMasterSpriteWorldP, gPowerUpSpriteLayerP, gTankSpriteLayerP);
-
- // Make sure no errors occurred during a MoveProc, etc.
- FatalError( SWStickyError() );
-
- SWAnimateMultiScreenSpriteWorld(gMasterSpriteWorldP);
- SWAnimateMultiScreenSpriteWorld(gCloneSpriteWorldP);
- SWFinishMultiScreenAnimation(gMasterSpriteWorldP);
-
- frames++;
- }
- }
-
- ShowResults(frames);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ShutDown (clean up and dispose of the SpriteWorlds)
- ///--------------------------------------------------------------------------------------
-
- void ShutDown( void )
- {
- SWDisposeDuplicateSpriteWorld(gCloneSpriteWorldP);
- SWDisposeSpriteWorld(&gMasterSpriteWorldP);
- SWExitSpriteWorld();
-
- FlushEvents(everyEvent, 0);
- ShowCursor();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // TileChangeProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void TileChangeProc(
- SpriteWorldPtr spriteWorldP)
- {
- short curImage;
- static short wallDelay = 0, oldTicks = 0;
- static short direction = 1;
- short ticksPassed, ticks;
-
- // Initialize oldTicks the first time this function is called
- if (oldTicks == 0)
- oldTicks = TickCount();
-
- ticks = TickCount();
- ticksPassed = ticks - oldTicks; // Number of ticks passed since last call
- oldTicks = ticks;
-
- // kWallTile
- wallDelay += ticksPassed;
- if (wallDelay >= kLavaFrameRate)
- {
- curImage = spriteWorldP->curTileImage[kFirstLavaTile];
-
- // Cycling mode
- if (curImage < kLastLavaTile)
- curImage++;
- else
- {
- curImage = kFirstLavaTile;
- }
-
-
- /* // Patrolling mode
- if (curImage == kLastLavaTile && direction > 0)
- direction = -1;
- else if (curImage == kFirstLavaTile && direction < 0)
- direction = 1;
-
- curImage += direction;
- */
-
- SWChangeTileImage(gMasterSpriteWorldP, kFirstLavaTile, curImage);
- SWChangeTileImage(gCloneSpriteWorldP, kFirstLavaTile, curImage);
- wallDelay = 0;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ScrollingWorldMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void ScrollingWorldMoveProc(
- SpriteWorldPtr spriteWorldP,
- SpritePtr followSpriteP)
- {
- short screenWidth, screenHeight, spriteWidth, spriteHeight;
- short horizPos, vertPos;
-
- screenWidth = (spriteWorldP->visScrollRect.right - spriteWorldP->visScrollRect.left);
- screenHeight = (spriteWorldP->visScrollRect.bottom - spriteWorldP->visScrollRect.top);
- spriteWidth = (followSpriteP->destFrameRect.right - followSpriteP->destFrameRect.left);
- spriteHeight = (followSpriteP->destFrameRect.bottom - followSpriteP->destFrameRect.top);
-
- horizPos = followSpriteP->destFrameRect.left + spriteWidth/2 - screenWidth/2;
- vertPos = followSpriteP->destFrameRect.top + spriteHeight/2 - screenHeight/2;
-
- if (kInterlacedMode)
- vertPos = vertPos>>1<<1;
-
- SWMoveVisScrollRect(spriteWorldP, horizPos, vertPos);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // UpdateKeys (Put the latest key values in the gKeys structure)
- ///--------------------------------------------------------------------------------------
-
- void UpdateKeys( void )
- {
- EventRecord event;
- short theKey;
- Boolean isDown;
-
- while ( GetOSEvent( (keyUpMask | keyDownMask), &event ) )
- {
- theKey = (event.message & keyCodeMask) >> 8;
- isDown = (event.what != keyUp);
-
- switch (theKey)
- {
- // Tank 1 keys
- case kLeftPlayer1Key:
- gTank1Keys.left = isDown;
- break;
- case kRightPlayer1Key:
- gTank1Keys.right = isDown;
- break;
- case kDownPlayer1Key:
- gTank1Keys.down = isDown;
- break;
- case kUpPlayer1Key:
- gTank1Keys.up = isDown;
- break;
- case kShootPlayer1Key:
- gTank1Keys.shoot = isDown;
- break;
-
- // Tank 2 keys
- case kLeftKeyPad:
- gTank2Keys.left = isDown;
- break;
- case kRightKeyPad:
- gTank2Keys.right = isDown;
- break;
- case kDownKeyPad:
- gTank2Keys.down = isDown;
- break;
- case kUpKeyPad:
- gTank2Keys.up = isDown;
- break;
- case kShootKeyPad:
- gTank2Keys.shoot = isDown;
- break;
- }
- }
- }
-
-